home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 4
/
Aminet 4 - November 1994.iso
/
aminet
/
comm
/
net
/
spakparnet_0_5.lha
/
srv
/
srv.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-11-09
|
6KB
|
229 lines
/********************************************************************
** NETWORK FILE SYSTEM SERVICE v0.5
**
** (c) Spak, Darrell Tam, c9107253@ee.newcastle.edu.au (1994)
** phone (Australia) 049-829-710
** 49-829-710
** (c) SST Jan-Feb-Mar 1994
**
** A NETWORK FILE SYSTEM SERVICE WHICH REGISTERS WITH ParServer or
** compatible servers
**
** the format of the messages sent/received are as shown in parstuff.h
** which is a "generic" format
**
** features:
** - all operations are totally asynchronous
** - reading is double buffered for best performance (hence the code!)
**
** bugs:
** - writing is not double buffered
**
**
** TABS to 4
********************************************************************/
#include "/snd/everything.h"
#include <st/st_proto.h>
#include <string.h>
#include "nfsinternal.h"
#include "nfsglobs_protos.h"
#include "nfsopen_protos.h"
#include "nfsclose_protos.h"
#include "nfsread_protos.h"
#include "nfswrite_protos.h"
#include "nfsseek_protos.h"
#include "nfslock_protos.h"
#include "nfsfreelock_protos.h"
#include "nfswaitchar_protos.h"
#include "nfsexamine_protos.h"
short netport = SERV_FILE; /* network "port" number */
char *netregname = "ParRegister"; /* server to "register" with */
/********************************************************************/
void CleanUp(void)
/********************************************************************/
{
/** REMOVE US AS A SERVER FROM THE THING */
if(registered) {
struct RegisterMsg rm;
struct Message *maj;
INIT_REGISTERMSG(&rm, ourport, RM_REMOVE_SERVER, netport, NULL, NULL);
for(PutMsg(parport, &rm); (WaitPort(ourport), (maj = GetMsg(ourport)) != &rm);)
ReplyMsg(maj); /* important to return all messages but ours */
}
if(ourport) DeletePort(ourport);
if(dosport) DeletePort(dosport);
if(GfxBase) CloseLibrary((struct Library *)GfxBase);
if(IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
}
/********************************************************************/
short InitStuff(void)
/********************************************************************/
{
out = Output();
if(!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 0))
|| !(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 0)) )
return(0);
if(!(ourport = CreatePort(0,0)) || /* port to send packs to */
!(dosport = CreatePort(0,0))) { /* comms with dos */
fpf(out, "No ports\n");
return(0);
}
if(!(parport = FindPort(netregname)) ) {
fpf(out, "Couldn't find '%s'\n", netregname);
return(0);
}
/** REGISTER WITH THE PARALLEL THING */
{
struct RegisterMsg rm;
INIT_REGISTERMSG(&rm, ourport, RM_ADD_SERVER, netport, ourport, NULL);
PutMsg(parport, &rm); WaitPort(ourport); GetMsg(ourport);
if(rm.smsg.result != (long)ourport) {
fpf(out, "Netport (%ld) is already in use ('%s')\n",
netport,
((struct MsgPort *)rm.smsg.result)->mp_Node.ln_Name);
return(0);
}
registered = 1;
fpf(out, "Registered ok (netport=%ld)\n", netport);
}
return(1);
}
/********************************************************************/
void DoMajic(void)
/********************************************************************/
{
unsigned long mask, waitmask, pmask, dmask;
register struct PktMsgRecv *pmr;
waitmask = (pmask = 1<<ourport->mp_SigBit) |
(dmask = 1<<dosport->mp_SigBit) |
SIGBREAKF_CTRL_C;
fpf(out, "Waiting for requests\n");
while(/* packets outstanding && */
stillgoing && !((mask = Wait(waitmask)) & SIGBREAKF_CTRL_C)) {
/** THIS PORT IS ONLY MEANT FOR DIRECT-COMMS WITH THE SERVER */
if(mask & pmask) while(pmr = (struct PktMsgRecv *)GetMsg(ourport) ) {
#ifdef DEBUG
fpf(out,"nfs: recv (msg=%lx, type=%ld, alloclen=%ld)\n",
pmr, pmr->pm.smsg.type, pmr->pm.smsg.alloclen);
#endif
switch(pmr->pm.smsg.type) {
case TYPE_RECEIVED: {
struct NFSDummy *nfs_req = (void *)pmr->req_body;
/* the action table with action numbers shown */
static void *(* action[])(struct PktMsgRecv *) = {
srv_examinelock, /* 0 */
srv_openfile, /* 1 */
srv_closefile, /* 2 */
srv_read, /* 3 */
srv_write, /* 4 */
srv_seek, /* 5 */
srv_lock, /* 6 */
srv_freelock, /* 7 */
srv_waitchar, /* 8 */
srv_copylock, /* 9 */
srv_examinenext, /* 10 */
};
register void *err_mem;
register long request;
#ifdef DEBUG
fpf(out, "nfs: action=%ld\n", nfs_req->request);
#endif
/** CHANGE THE NET-SERVER-MESSAGE INTO ONE FOR US */
INIT_MSG(&pmr->pm.smsg.msg, ourport, sizeof(*pmr));
if((request = nfs_req->request) < (sizeof(action)/sizeof(void *)))
err_mem = action[request](pmr);
else
err_mem = &nfs_res_fail;
/** IF THERE WAS A BAD ERROR RETURN THE PACKET IMMEDIATELY */
if(err_mem) {
if(nfs_req->sr.return_len) {
pmr->user.user1 = NULL; /* free on return */
INTERNAL_PREP_PKTMSG_DMA(&pmr->pm,
EMEM_RETURNMSG,
SERV_RETURN,
err_mem, nfs_req->sr.return_len);
PUT_STDMSG(&pmr->pm.smsg,
pmr->dmaport, TYPE_INTERNAL_SEND);
}
else FREE_PKTMSGRECV(pmr);
}
}
break;
/** DMA PACKET RETURNED (FREE MEM IF NO ROUTINE) */
case TYPE_RETURN: {
/* for the moment ignore send-errors ... */
if((long)pmr->user.user1)
pmr->user.user1(pmr);
else
FREE_PKTMSGRECV(pmr); /* free the message */
}
break;
/** SERVER TRYING TO KILL US ? */
case TYPE_QUIT: {
stillgoing = 0;
ReplyMsg(pmr);
}
break;
/** DUNNO WHAT THIS IS BUT REPLY TO IT ANYWAY */
default:
ReplyMsg(pmr);
}
}
/** GET RETURN PACKET FROM DOS (call the function contained in the dosmsg) */
if(mask & dmask) {
struct DosMsg *dm;
while(dm = (struct DosMsg *)GetMsg(dosport))
if(dm->code) dm->code(dm);
}
}
}
/********************************************************************/
int main(int argc, char *argv[])
/********************************************************************/
{
struct Process *pr = (void *)FindTask(NULL);
void *olddoswindow;
/* if(argc >= 1) {
netregname = argv[1]; /* eg "ParServer" */
if(argc >= 2)
netport = atoi(argv[2]);
} */
olddoswindow = pr->pr_WindowPtr;
pr->pr_WindowPtr = (void *)-1; /* turn off dos-request windows */
if(InitStuff()) DoMajic();
CleanUp();
pr->pr_WindowPtr = olddoswindow;
}